#!/bin/bash

#编码
#export LC_ALL="zh_CN.gbk"   export LANG="zh_CN.gbk"


#获取当前日期
today=$(date +%Y%m%d)
echo "---------------------------当前时间：$(date +%Y-%m-%d) $(date "+%H:%M:%S")---------------------------"
#计数
count=0

#判断该文件是否存在.ok文件
is_ok() {
  filepath="$1"
  if [[ ${1}  =~  ".ok" ]]; then
    echo "1"
    return 1
  fi
  okpath=${1}".ok"
  if [ -f "$okpath" ]; then
    echo "1"
    return 1
  else
    echo "0"
    return 0
  fi
}

#新建.ok文件
new_ok() {
  filepath="$1"
  if [ ! -d "$filepath"".ok" ]; then
    touch "$filepath"".ok"
  else
    echo "ok文件已经存在"
  fi
}

#企业微信机器人通知
robot_msg() {
  if [ "$count" == 0 ]; then
	return
  fi
  webHookUrl="$1"
  content=${@:2}
  content=${content//\ /}
  content=${content//\"/}
  date=$(date +%Y-%m-%d)
  time=$(date "+%H:%M:%S") 
  #企业微信机器人公共配置
  webHookUrlPub="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=cbcbe02a-63ef-4af6-98d4-c1f031bd31f7"
  # 获取内存占用
  mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100}')
  
  content="  **文件搬运日志**\n   >运行时间：$date.$time\n   >内存占用：$mem_usage%\n   >文件个数：$count\n  >运行日志：$content"
  webHookUrl=${webHookUrl}
  content='{"msgtype": "markdown","markdown": {"content": "'$content'"}}'
  echo "content : $content"
  echo "$webHookUrl"
  curl -H "Content-Type:application/json" -X POST --data-ascii "$content" $webHookUrl
  echo "$webHookUrlPub"
  curl -H "Content-Type:application/json" -X POST --data-ascii "$content" $webHookUrlPub
  echo "over!"
}

#本地文件传输方法
local_cp() {
  echo "-----进行本地文件传输-----"
  if [ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ]; then
    localpath="$1"
    echo "当前文件路径：$localpath"
    targetpath="$2"
    echo "目标文件路径：$targetpath"
    ok_type="$3"
    echo "ok方案：$ok_type"
  else
    echo "参数有误：当前文件路径，目标文件路径，ok方案"
    if [ "$wx_notice" = "yes" ]; then
      wx_msg="参数有误：当前文件路径，目标文件路径，ok方案"
    fi
    return
  fi
  echo "开始进行文件传输"
  #是否验证.ok
  if [ "$ok_type" = "10" -o "$ok_type" = "11" ]; then
    file_path=${localpath}
    echo "-验证ok文件：${file_path}"
    isok=$(is_ok "$file_path")
    if [ "$isok" = "0" ]; then
      echo "未找到ok文件，完毕"
      return
    fi
    echo "ok文件存在，继续"
  fi
  #文件夹不存在则创建
  if [ ! -d "$targetpath" ]; then
    mkdir -p "$targetpath"
  fi

  cp -a -f "$localpath" "$targetpath"

  #是否需要生成.ok
  if [ "$ok_type" = "01" -o "$ok_type" = "11" ]; then
    touch ${file_name}.ok
  fi

  echo "-----文件传输完毕-----"
}

#远程Scp传输文件
scp_file() {
  echo "-----进行SCP文件传输-----"

  #参数  远程ip  端口 用户名 密码  本地路径  远程路径 ok方案  单个文件名
  if [ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ] && [ -n "$7" ]; then
    rip="$1"
    rport="$2"
    ruser="$3"
    rpwd="$4"
    localpath="$5"
    targetpath="$6"
    ok_type="$7"

    if [ -n "$8" ]; then
      #如果有第8个参数，为上传单个文件，否则为上传文件夹
      echo "上传单个文件"
      lfile_name="$8"

      #是否验证.ok
      if [ "$ok_type" = "10" -o "$ok_type" = "11" ]; then
        flocalpath=${localpath}/${lfile_name}
        echo "-验证ok文件：${flocalpath}"
        isok=$(is_ok "$flocalpath")
        if [ "$isok" = "0" ]; then
          echo "未找到ok文件，完毕"
          return
        fi
        echo "ok文件存在，继续"
      fi
      #新建远程文件夹
      /usr/bin/expect <<EOF
spawn ssh ${ruser}@${rip}
expect {
	"yes/no" { send "yes\r"; exp_continue }
	"password:" { send "${rpwd}\r" }
  }
  expect "100%"
  send "mkdir ${targetpath}\r"
	#是否需要生成.ok
  if { "$ok_type"=="01" || "$ok_type"=="11" } {
	  send "touch ${targetpath}/${lfile_name}.ok\r"
  }
  expect "eof"
EOF

      /usr/bin/expect <<EOF
    spawn scp -P ${rport}  ${flocalpath} ${ruser}@${rip}:${targetpath}/
    expect {
    "(yes/n?"
      {
      send "yes\n"
      expect "*assword:" { send "$rpwd\r" }
      }
    "*assword:"
      {
      send "$rpwd\r"
      }
    }
    expect eof
EOF
    else
      #直接上传文件夹
      /usr/bin/expect <<EOF
    spawn scp -r  -P ${rport}  ${localpath} ${ruser}@${rip}:${targetpath}/
    expect {
    "(yes/n?"
      {
      send "yes\n"
      expect "*assword:" { send "$rpwd\r" }
      }
    "*assword:"
      {
      send "$rpwd\r"
      }
    }
    expect eof
EOF
    fi

  else
    echo "参数有误：远程ip  端口 用户名  密码  本地路径  远程路径 ok方案  单个文件名"
    if [ "$wx_notice" = "yes" ]; then
      wx_msg="参数有误：远程ip  端口 用户名  密码  本地路径  远程路径 ok方案  单个文件名"
    fi
  fi
}

#远程sftp传输文件
sftp_file() {
  echo "-----进行SFTP文件传输-----"

  #参数  远程ip 端口 用户名 密码  本地路径  远程路径 ok方案   传输类型  单个文件名
  if [ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ] && [ -n "$7" ] && [ -n "$8" ]; then
    sftp_ip="$1"
    sftp_port="$2"
    sftp_user="$3"
    sftp_password="$4"
    localpath="$5"
    targetpath="$6"
    ok_type="$7"
    trans_type="$8"

    #判断传输类型
    if [ "$trans_type" = "0" ]; then
      echo "进行文件拉取。。。"
	  mkdir -p ${localpath}
	  #判断是否需要防止重复拉取，是的话先下载到临时目录再进行鉴别
	  if [ "$ok_type" = "11" -o "$ok_type" = "10" ]; then
          check_ok=1
		  localpath0=${localpath}
		  localpath=${localpath}"_temp"
        fi
      if [ -n "$9" ]; then
        #如果有第9个参数，为拉取单个文件，否则为拉取文件夹
        echo "拉取单个文件"
        file_name="$9"
		#是否需要生成.ok
        if [ "$ok_type" = "01" -o "$ok_type" = "11" ]; then
          create_ok=1
        fi
		
        #实现SFTP传输单个文件
        /usr/bin/expect <<EOF
  #每次执行sftp命令超时时间，如果设置过小会导致大文件传输不完整，  单位:秒
  set timeout  10000

  #执行连接SFTP
  spawn  /export/conf/openssh-portable-V_8_1_P1/sftp -oPort=${sftp_port} ${sftp_user}@${sftp_ip}
  #反馈字符串包含 passowrd,则发送密码
    expect {
    "(yes/n?"
      {
      send "yes\n"
      expect "*assword:" { send "$sftp_password\r" }
      }
    "*assword:"
      {
      send "$sftp_password\r"
      }
    }

  #SFTP cd到本地文件目录
  expect "sftp>"
  send "lcd ${localpath}\r"

  #SFTP cd到sftp服务器下
  expect "sftp>"
  send "cd ${targetpath}\r"

  #SFTP 将cd目录下文件，传输到lcd目录下
  expect "sftp>"
  send "get ${file_name}\r"
  #关闭SFTP连接
  expect "sftp>"
EOF
		wx_msg=${targetpath}"/"${file_name}"文件下载至"${localpath}
        #是否需要生成.ok
		file_path=${localpath}/${file_name}
        if [  "$create_ok" = "1" ]&&[  -f "$file_path" ]; then
          touch ${file_path}.ok
          echo "ok文件生成"
        fi
      else
        #实现SFTP传输文件夹
        echo "拉取文件夹"
		mkdir -p ${localpath}
        /usr/bin/expect <<EOF
  #每次执行sftp命令超时时间，如果设置过小会导致大文件传输不完整，  单位:秒
  set timeout  10000

  #执行连接SFTP
  spawn  /export/conf/openssh-portable-V_8_1_P1/sftp -oPort=${sftp_port} ${sftp_user}@${sftp_ip}
  #反馈字符串包含 passowrd,则发送密码
    expect {
    "(yes/n?"
      {
      send "yes\n"
      expect "*assword:" { send "$sftp_password\r" }
      }
    "*assword:"
      {
      send "$sftp_password\r"
      }
    }

  #SFTP cd到sftp服务器下
  expect "sftp>"
  send "cd ${targetpath}\r"

  #SFTP 将lcd目录下文件夹下载
  expect "sftp>"
  send "get -r  ${targetpath}/.  ${localpath}\r"

  #删除路径下ok文件
  #expect "sftp>"
  #send "rm *.ok\r"
  #关闭SFTP连接
  expect "sftp>"
EOF
	  wx_msg=${targetpath}"文件下载至"${localpath}
		  #是否校验ok文件，校验的话先下载到了临时目录
		  if [  "$check_ok" = "1" ] ; then
			  echo "检查临时文件夹ok文件${localpath}"
			  for f in `ls $localpath`
				do
					echo "遍历项------$localpath/$f"
				   if [ -f "$localpath/$f" ]                       #   $dir/$f    保障路径正确                               
				   then                                                                                          
					  isok=$(is_ok "$localpath/$f")
					if [ "$isok" = "1" ]; then
						echo "本地ok文件存在不予处理"
					else
						let count++
						echo "复制文件并在临时目录生成ok文件$count"
						cp -a -f "$localpath/$f" "$localpath0"
						touch "$localpath/$f"".ok"
					fi
				  elif [ -d "$localpath/$f" ]                                                                     
				  then                                                                                      
					  echo "$localpath/$f是目录"                                                                                                                   
				  else                                                                                      
					  echo "$localpath/$f未知"                                                                    
				  fi                                                                                                                                                                              
				done
			#删除临时文件夹
			#rm -rf "$localpath"
			chmod -R 777 ${localpath0}
          fi
		  chmod -R 777 ${localpath}
      fi
      echo "文件传输完毕"
      
    elif
      [ "$trans_type" = "1" ]
    then
      echo "进行文件上传。。。"
      if [ -n "$9" ]; then
        #如果有第8个参数，为上传单个文件，否则为上传文件夹
        echo "传输单个文件"
        file_name="$9"
        #是否验证.ok
        if [ "$ok_type" = "10" -o "$ok_type" = "11" ]; then
          file_path=${localpath}/${file_name}
          echo "-验证ok文件：${file_path}"
          isok=$(is_ok "$file_path")
          if [ "$isok" = "0" ]; then
            echo "未找到ok文件，完毕"
            return
          fi
          echo "ok文件存在，继续"
        fi
        #实现SFTP传输单个文件
        /usr/bin/expect <<EOF
  #每次执行sftp命令超时时间，如果设置过小会导致大文件传输不完整，  单位:秒
  set timeout  10000

  #执行连接SFTP
  spawn  /export/conf/openssh-portable-V_8_1_P1/sftp -oPort=${sftp_port} ${sftp_user}@${sftp_ip}
  #反馈字符串包含 passowrd,则发送密码
    expect {
    "(yes/n?"
      {
      send "yes\n"
      expect "*assword:" { send "$sftp_password\r" }
      }
    "*assword:"
      {
      send "$sftp_password\r"
      }
    }
  #SFTP cd到本地文件目录
  expect "sftp>"
  send "lcd ${localpath}\r"

  #SFTP cd到sftp服务器下
  expect "sftp>"
  send "mkdir  ${targetpath}\r"
  expect "sftp>"
  send "cd ${targetpath}\r"

  #SFTP 将lcd目录下文件，传输到cd目录下
  expect "sftp>"
  send "put ${file_name}\r"

  #是否需要生成.ok
  if { "$ok_type"=="01" || "$ok_type"=="11" } {
	  expect "sftp>"
	  send "!touch ${file_name}.ok\r"
	  
	  expect "sftp>"
	  send "put ${file_name}.ok\r"
  }
  #关闭SFTP连接
  expect "sftp>"
EOF
      wx_msg=${localpath}"/"${file_name}"文件已上传至"${targetpath}
      else
        #实现SFTP传输文件夹,不支持ok校验
        echo "上传文件夹"
        #将.ok文件放入临时ok文件夹，先上传其他文件，再上传ok文件
	cd ${localpath}
	mkdir ok
	mv *.ok ok

        /usr/bin/expect <<EOF
  #每次执行sftp命令超时时间，如果设置过小会导致大文件传输不完整，  单位:秒
  set timeout  10000

  #执行连接SFTP
  spawn  /export/conf/openssh-portable-V_8_1_P1/sftp -oPort=${sftp_port} ${sftp_user}@${sftp_ip}
  #反馈字符串包含 passowrd,则发送密码
    expect {
    "(yes/n?"
      {
      send "yes\n"
      expect "*assword:" { send "$sftp_password\r" }
      }
    "*assword:"
      {
      send "$sftp_password\r"
      }
    }

  #SFTP cd到sftp服务器下
  expect "sftp>"
  send "mkdir ${targetpath}\r"
  expect "sftp>"
  send "cd ${targetpath}\r"

  #SFTP 将lcd目录下文件夹上传,先上传其他类型 txt zip，再上传ok文件
  expect "sftp>"
  send "put   ${localpath}/* \r"
  
  expect "sftp>"
  send "put   ${localpath}/ok/* \r" 
  
  #关闭SFTP连接
  expect "sftp>"
EOF
	  wx_msg=${localpath}"文件已上传至"${targetpath}
	  #还原ok文件
	  mv ./ok/*  ./
	  count=`find ${localpath} -maxdepth 1 -type f |wc -l`
      fi
      echo "文件传输完毕$count"
    else
      echo "传输类型有误！！！"
      return
    fi

  else

    echo "参数有误：参数  远程ip 端口 用户名 密码  本地路径  远程路径 ok方案   传输类型  （单个文件名）"
    if [ "$wx_notice" = "yes" ]; then
      wx_msg="参数有误：参数  远程ip 端口 用户名 密码  本地路径  远程路径 ok方案   传输类型  （单个文件名）"
    fi
  fi
}

#sftp下载文件夹，需要校验.ok文件----暂不使用
sftp_dir_down() {
	echo "-----进行SFTP遍历文件夹下载-----"
	sftp_ip="$1"
    sftp_port="$2"
    sftp_user="$3"
    sftp_password="$4"
    localpath="$5"
    targetpath="$6"
    ok_type="$7"
    trans_type="$8"
	
	mkdir -p ${localpath}
	
        #实现SFTP传输单个文件
        /usr/bin/expect <<EOF
  #每次执行sftp命令超时时间，如果设置过小会导致大文件传输不完整，  单位:秒
  set timeout  10000

  #执行连接SFTP
  spawn  /export/conf/openssh-portable-V_8_1_P1/sftp -oPort=${sftp_port} ${sftp_user}@${sftp_ip}
  #反馈字符串包含 passowrd,则发送密码
  expect {
   "*password:" { send "${sftp_password}\r" }
  }

  #SFTP cd到本地文件目录
  expect "sftp>"
  send "lcd ${localpath}\r"

  #SFTP cd到sftp服务器下
  expect "sftp>"
  send "cd ${targetpath}\r"
  
  #是否校验.ok文件
  if { "$ok_type"=="10" || "$ok_type"=="11" } {
		expect "sftp>"
		send "ls ${file_name}.ok\r"
		expect {
		"*not found" {
			send_user "未找到ok文件，完毕\r";
			send "exit\r"
			}
		send_user "ok文件存在，继续"
	  }
  }

  #SFTP 将cd目录下文件，传输到lcd目录下
  expect "sftp>"
  send "get ${file_name}\r"
  #关闭SFTP连接
  expect "sftp>"
EOF

}

################方法调用区################

#企业微信机器人调用测试
#robot_msg "10.8.32.8:8888/cgi-bin/webhook/send?key=4c1ee8fc-549e-48f7-a2e7-42462d55d21e" "ok了1111111"

#生成.ok文件测试
#new_ok  "/usr/test/test.txt"

#scp传输测试
#scp_file 172.23.48.100  gmyl   aIAMDwixpTk8e   /usr/test   /export/test

#sftp传输测试
#sftp_file 172.23.48.100   22  gmyl   aIAMDwixpTk8e   /home/gmyl/test  /home/gmyl/demo/aaa    11 0    111.txt

#is_ok "/usr/test/20230320/test1.txt"
########################################
